package com.chenye.rabbitmq.rabbit;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by chenye on 2018/4/15.
 */
@Configuration
public class RabbitConfig {
    final static String MESSAGE = "topic.message";
    final static String MESSAGES = "topic.messages";

    @Bean
    public Queue messageQueue(){
        return new Queue(RabbitConfig.MESSAGE);
    }
    @Bean
    public Queue messagesQueue(){
        return new Queue(RabbitConfig.MESSAGES);
    }
    @Bean
    public Queue testQueue(){
        return new Queue("topic.test");
    }

    @Bean
    public TopicExchange exchange() {
        return new TopicExchange("exchange");
    }
    @Bean
    Binding bindingExchangeMessage(Queue messageQueue, TopicExchange exchange) {
        return BindingBuilder.bind(messageQueue).to(exchange).with("topic.message");
    }

    @Bean
    Binding bindingExchangeMessages(Queue messagesQueue, TopicExchange exchange) {
        return BindingBuilder.bind(messagesQueue).to(exchange).with("topic.#");
    }
    @Bean
    Binding bindingExchangeTest(Queue testQueue, TopicExchange exchange) {
        return BindingBuilder.bind(testQueue).to(exchange).with("topic.test");
    }


    @Bean
    public Queue AMessage() {
        return new Queue("fanout.A");
    }

    @Bean
    public Queue BMessage() {
        return new Queue("fanout.B");
    }

    @Bean
    public Queue CMessage() {
        return new Queue("fanout.C");
    }
    //广播模式
    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

    @Bean
    Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(CMessage).to(fanoutExchange);
    }

    //延时对列
    public static final String REPEAT_TRADE_QUEUE = "repeat.trade.queue";
    public static final String DLX_QUEUE = "dlx.queue";
    public static final String DLX_EXCHANGE = "dlx_exchange";
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("direct_exchange");
    }
    @Bean
    public Queue repeatTradeQueue(){
        return new Queue(RabbitConfig.REPEAT_TRADE_QUEUE);
    }
    @Bean
    public Binding repeatTradeBinding(){
        return BindingBuilder.bind(repeatTradeQueue()).to(directExchange()).with("repeat_routeKey");
    }
    @Bean
    public DirectExchange directTTLExchange(){
        return new DirectExchange("direct_ttl_exchange");
    }
    @Bean
    public Queue deadLetterQueue() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", "direct_exchange");
        arguments.put("x-dead-letter-routing-key", "repeat_routeKey");
        Queue queue = new Queue(RabbitConfig.DLX_QUEUE,true,false,false,arguments);
        System.out.println("arguments :" + queue.getArguments());
        return queue;
    }

    @Bean
    public Binding  deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue()).to(directTTLExchange()).with("ttl_routeKey");
    }


    @Bean
    public Queue userQueue(){
        return new Queue("user");
    }

    @Bean
    public Queue helloQueue(){
        return new Queue("hello");
    }
    //test durable 重启rabbitmq服务后durable属性为false的对列都被清除了。
    @Bean
    public Queue durable(){
        return new Queue("test-durable",false);
    }
    /**
     * 配置第一个rabbitmq连接
     */
    @Bean(name="firstConnectionFactory")
    @Primary
    public ConnectionFactory firstConnectionFactory(
            @Value("${spring.rabbitmq.first.host}") String host,
            @Value("${spring.rabbitmq.first.port}") int port,
            @Value("${spring.rabbitmq.first.username}") String username,
            @Value("${spring.rabbitmq.first.password}") String password){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }
    @Bean(name="firstRabbitTemplate")
    @Primary
    public RabbitTemplate firstRabbitTemplate(
            @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory){
        RabbitTemplate firstRabbitTemplate = new RabbitTemplate(connectionFactory);
        return firstRabbitTemplate;
    }
    @Bean(name="firstFactory")
    public SimpleRabbitListenerContainerFactory firstFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    /**
     * 配置第二个rabbitmq连接
     */
    @Bean(name="secondConnectionFactory")
    public ConnectionFactory secondConnectionFactory(
            @Value("${spring.rabbitmq.second.host}") String host,
            @Value("${spring.rabbitmq.second.port}") int port,
            @Value("${spring.rabbitmq.second.username}") String username,
            @Value("${spring.rabbitmq.second.password}") String password){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }
    @Bean(name="secondRabbitTemplate")
    public RabbitTemplate secondRabbitTemplate(
            @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory){
        RabbitTemplate secondRabbitTemplate = new RabbitTemplate(connectionFactory);
        return secondRabbitTemplate;
    }
    @Bean(name="secondFactory")
    public SimpleRabbitListenerContainerFactory secondFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    @Bean
    public Queue secondQueue(){
        return new Queue("secondQueue",true, false,false);
    }
//    @Bean
//    public DirectExchange secondExchange(){
//        return new DirectExchange("secondExchange",true,false);
//    }
//    @Bean
//    public Binding secondBinding(){
//        return BindingBuilder.bind(secondQueue()).to(secondExchange()).with("secondRouteKey");
//    }

}
